package com.example.sudokugame

import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.example.sudokugame.databinding.ActivityGameBinding
import com.example.sudokugame.models.*
import com.example.sudokugame.network.NetworkManager
import com.example.sudokugame.views.SudokuGridView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.launch
import java.util.*
import kotlin.collections.ArrayList

class GameActivity : AppCompatActivity(), SudokuGridView.OnCellSelectedListener {
    
    private lateinit var binding: ActivityGameBinding
    private lateinit var gameState: GameState
    private var selectedRow = -1
    private var selectedCol = -1
    
    private var timer: Timer? = null
    private val handler = Handler(Looper.getMainLooper())
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityGameBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        val difficulty = intent.getStringExtra("difficulty") ?: "easy"
        initializeGame(difficulty)
        setupClickListeners()
        setupSudokuGrid()
    }
    
    private fun initializeGame(difficultyString: String) {
        val difficulty = when (difficultyString) {
            "easy" -> Difficulty.EASY
            "medium" -> Difficulty.MEDIUM
            "hard" -> Difficulty.HARD
            "expert" -> Difficulty.EXPERT
            else -> Difficulty.EASY
        }
        
        binding.tvDifficulty.text = difficulty.displayName
        
        // 显示加载中
        showLoading()
        
        // 从服务器获取数独题目
        lifecycleScope.launch {
            try {
                val response = NetworkManager.apiService.getPuzzle(difficulty.value)
                if (response.isSuccessful && response.body() != null) {
                    val puzzleData = response.body()!!.data
                    initializeGameState(puzzleData, difficulty)
                    hideLoading()
                } else {
                    // 网络失败，生成本地题目
                    generateLocalPuzzle(difficulty)
                    hideLoading()
                }
            } catch (e: Exception) {
                // 网络异常，生成本地题目
                generateLocalPuzzle(difficulty)
                hideLoading()
            }
        }
    }
    
    private fun initializeGameState(puzzleData: SudokuPuzzleData, difficulty: Difficulty) {
        val grid = Array(9) { row ->
            Array(9) { col ->
                val value = puzzleData.puzzle[row][col]
                SudokuCell(
                    value = value,
                    isFixed = value != 0
                )
            }
        }
        
        gameState = GameState(
            puzzle = grid,
            difficulty = difficulty,
            puzzleId = puzzleData.id
        )
        
        binding.sudokuGrid.setGrid(grid)
        updateUI()
        
        // 自动启动计时器
        startTimer()
    }
    
    private fun generateLocalPuzzle(difficulty: Difficulty) {
        // 简单的本地题目生成（在实际应用中应该有更复杂的算法）
        val grid = Array(9) { Array(9) { SudokuCell() } }
        
        // 这里简化处理，添加一些固定数字
        val preset = arrayOf(
            intArrayOf(5, 3, 0, 0, 7, 0, 0, 0, 0),
            intArrayOf(6, 0, 0, 1, 9, 5, 0, 0, 0),
            intArrayOf(0, 9, 8, 0, 0, 0, 0, 6, 0),
            intArrayOf(8, 0, 0, 0, 6, 0, 0, 0, 3),
            intArrayOf(4, 0, 0, 8, 0, 3, 0, 0, 1),
            intArrayOf(7, 0, 0, 0, 2, 0, 0, 0, 6),
            intArrayOf(0, 6, 0, 0, 0, 0, 2, 8, 0),
            intArrayOf(0, 0, 0, 4, 1, 9, 0, 0, 5),
            intArrayOf(0, 0, 0, 0, 8, 0, 0, 7, 9)
        )
        
        for (row in 0..8) {
            for (col in 0..8) {
                val value = preset[row][col]
                grid[row][col] = SudokuCell(
                    value = value,
                    isFixed = value != 0
                )
            }
        }
        
        gameState = GameState(
            puzzle = grid,
            difficulty = difficulty,
            puzzleId = "local_${System.currentTimeMillis()}"
        )
        
        binding.sudokuGrid.setGrid(grid)
        updateUI()
        
        // 自动启动计时器
        startTimer()
        
        Toast.makeText(this, "离线模式：使用本地题目", Toast.LENGTH_SHORT).show()
    }
    
    private fun setupClickListeners() {
        // 数字按钮
        val numberButtons = listOf(
            binding.btnNumber1, binding.btnNumber2, binding.btnNumber3,
            binding.btnNumber4, binding.btnNumber5, binding.btnNumber6,
            binding.btnNumber7, binding.btnNumber8, binding.btnNumber9
        )
        
        numberButtons.forEachIndexed { index, button ->
            button.setOnClickListener {
                if (selectedRow != -1 && selectedCol != -1) {
                    setCellValue(selectedRow, selectedCol, index + 1)
                }
            }
        }
        
        // 功能按钮
        binding.btnErase.setOnClickListener {
            if (selectedRow != -1 && selectedCol != -1) {
                setCellValue(selectedRow, selectedCol, 0)
            }
        }
        
        binding.btnHint.setOnClickListener {
            getHint()
        }
        
        binding.btnValidate.setOnClickListener {
            validateSudoku()
        }
        
        binding.btnPause.setOnClickListener {
            togglePause()
        }
        
        binding.btnResume.setOnClickListener {
            togglePause()
        }
    }
    
    private fun setupSudokuGrid() {
        binding.sudokuGrid.setOnCellSelectedListener(this)
    }
    
    override fun onCellSelected(row: Int, col: Int) {
        selectedRow = row
        selectedCol = col
        binding.sudokuGrid.setSelectedCell(row, col)
    }
    
    private fun setCellValue(row: Int, col: Int, value: Int) {
        if (!gameState.puzzle[row][col].isFixed) {
            gameState.puzzle[row][col].value = value
            gameState.puzzle[row][col].isError = false
            
            binding.sudokuGrid.setCellValue(row, col, value)
            
            // 检查是否完成
            if (gameState.isCompleted()) {
                onGameCompleted()
            }
            
            updateScore()
        }
    }
    
    private fun getHint() {
        if (selectedRow != -1 && selectedCol != -1 && 
            !gameState.puzzle[selectedRow][selectedCol].isFixed &&
            gameState.puzzle[selectedRow][selectedCol].isEmpty) {
            
            // 这里应该调用服务器API获取提示，暂时简化处理
            gameState.hintsUsed++
            gameState.puzzle[selectedRow][selectedCol].isHinted = true
            
            // 简单的提示：设置一个可能的值（实际应该有更智能的算法）
            val possibleValues = getPossibleValues(selectedRow, selectedCol)
            if (possibleValues.isNotEmpty()) {
                val hintValue = possibleValues.random()
                setCellValue(selectedRow, selectedCol, hintValue)
                Toast.makeText(this, "提示：${hintValue}", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this, "此位置没有可用提示", Toast.LENGTH_SHORT).show()
            }
            
            updateUI()
        } else {
            Toast.makeText(this, "请选择一个空白单元格", Toast.LENGTH_SHORT).show()
        }
    }
    
    private fun getPossibleValues(row: Int, col: Int): List<Int> {
        val used = mutableSetOf<Int>()
        
        // 检查行
        for (c in 0..8) {
            val value = gameState.puzzle[row][c].value
            if (value != 0) used.add(value)
        }
        
        // 检查列
        for (r in 0..8) {
            val value = gameState.puzzle[r][col].value
            if (value != 0) used.add(value)
        }
        
        // 检查3x3框
        val boxRow = row / 3 * 3
        val boxCol = col / 3 * 3
        for (r in boxRow until boxRow + 3) {
            for (c in boxCol until boxCol + 3) {
                val value = gameState.puzzle[r][c].value
                if (value != 0) used.add(value)
            }
        }
        
        return (1..9).filter { it !in used }
    }
    
    private fun validateSudoku() {
        lifecycleScope.launch {
            try {
                val grid = Array(9) { row ->
                    IntArray(9) { col ->
                        gameState.puzzle[row][col].value
                    }
                }
                
                val response = NetworkManager.apiService.validateSudoku(mapOf("grid" to grid))
                if (response.isSuccessful && response.body() != null) {
                    val isValid = response.body()!!.data.isValid
                    val message = response.body()!!.data.message
                    Toast.makeText(this@GameActivity, message, Toast.LENGTH_SHORT).show()
                    
                    if (!isValid) {
                        // 标记错误
                        markErrors()
                    }
                } else {
                    // 本地验证
                    localValidate()
                }
            } catch (e: Exception) {
                // 网络错误，使用本地验证
                localValidate()
            }
        }
    }
    
    private fun localValidate() {
        val errors = findErrors()
        if (errors.isEmpty()) {
            Toast.makeText(this, "目前没有发现错误", Toast.LENGTH_SHORT).show()
        } else {
            markErrors()
            Toast.makeText(this, "发现 ${errors.size} 个错误", Toast.LENGTH_SHORT).show()
        }
    }
    
    private fun findErrors(): List<Pair<Int, Int>> {
        val errors = mutableListOf<Pair<Int, Int>>()
        
        for (row in 0..8) {
            for (col in 0..8) {
                val value = gameState.puzzle[row][col].value
                if (value != 0 && !isValidPlacement(row, col, value)) {
                    errors.add(Pair(row, col))
                }
            }
        }
        
        return errors
    }
    
    private fun isValidPlacement(row: Int, col: Int, value: Int): Boolean {
        // 检查行
        for (c in 0..8) {
            if (c != col && gameState.puzzle[row][c].value == value) {
                return false
            }
        }
        
        // 检查列
        for (r in 0..8) {
            if (r != row && gameState.puzzle[r][col].value == value) {
                return false
            }
        }
        
        // 检查3x3框
        val boxRow = row / 3 * 3
        val boxCol = col / 3 * 3
        for (r in boxRow until boxRow + 3) {
            for (c in boxCol until boxCol + 3) {
                if ((r != row || c != col) && gameState.puzzle[r][c].value == value) {
                    return false
                }
            }
        }
        
        return true
    }
    
    private fun markErrors() {
        val errors = findErrors()
        
        // 清除之前的错误标记
        for (row in 0..8) {
            for (col in 0..8) {
                gameState.puzzle[row][col].isError = false
                binding.sudokuGrid.setCellError(row, col, false)
            }
        }
        
        // 标记新错误
        for ((row, col) in errors) {
            gameState.puzzle[row][col].isError = true
            binding.sudokuGrid.setCellError(row, col, true)
        }
        
        gameState.errorsCount = errors.size
        updateUI()
    }
    
    private fun togglePause() {
        when (gameState.status) {
            GameStatus.PLAYING -> {
                gameState.status = GameStatus.PAUSED
                gameState.elapsedTime = gameState.getElapsedSeconds()
                binding.pauseOverlay.visibility = View.VISIBLE
                binding.btnPause.text = "继续"
                stopTimer()
            }
            GameStatus.PAUSED -> {
                gameState.status = GameStatus.PLAYING
                gameState.startTime = System.currentTimeMillis()
                binding.pauseOverlay.visibility = View.GONE
                binding.btnPause.text = "暂停"
                startTimer()
            }
            else -> {}
        }
    }
    
    private fun onGameCompleted() {
        gameState.status = GameStatus.COMPLETED
        stopTimer()
        
        val finalTime = gameState.getElapsedSeconds()
        val finalScore = calculateFinalScore(finalTime)
        gameState.score = finalScore
        
        // 提交游戏结果
        submitGameResult(finalTime, finalScore)
    }
    
    private fun calculateFinalScore(timeInSeconds: Long): Int {
        val baseScore = when (gameState.difficulty) {
            Difficulty.EASY -> 100
            Difficulty.MEDIUM -> 200
            Difficulty.HARD -> 300
            Difficulty.EXPERT -> 500
        }
        
        val timeBonus = maxOf(0, (3600 - timeInSeconds).toInt()) // 1小时内完成有时间奖励
        val hintPenalty = gameState.hintsUsed * 10
        val errorPenalty = gameState.errorsCount * 5
        
        return maxOf(0, baseScore + timeBonus - hintPenalty - errorPenalty)
    }
    
    private fun submitGameResult(finalTime: Long, finalScore: Int) {
        lifecycleScope.launch {
            try {
                val grid = Array(9) { row ->
                    IntArray(9) { col ->
                        gameState.puzzle[row][col].value
                    }
                }
                
                val request = GameSubmitRequest(
                    puzzle = grid,
                    solution = null,
                    difficulty = gameState.difficulty.value,
                    score = finalScore,
                    time = finalTime,
                    completed = true
                )
                
                val response = NetworkManager.apiService.submitGame(request)
                if (response.isSuccessful && response.body() != null) {
                    val result = response.body()!!.data
                    showCompletionDialog(finalTime, finalScore, result)
                } else {
                    // 提交失败，仍然显示完成对话框
                    showCompletionDialog(finalTime, finalScore, null)
                }
            } catch (e: Exception) {
                // 网络错误，仍然显示完成对话框
                showCompletionDialog(finalTime, finalScore, null)
            }
        }
    }
    
    private fun showCompletionDialog(finalTime: Long, finalScore: Int, serverResult: GameSubmitData?) {
        val message = buildString {
            append("🎉 恭喜完成！\n\n")
            append("⏱️ 用时: ${formatTime(finalTime)}\n")
            append("🏆 分数: $finalScore\n")
            append("📊 难度: ${gameState.difficulty.displayName}\n")
            
            // 如果有服务器返回的排名信息，显示它
            serverResult?.let { result ->
                result.rank?.let { rank ->
                    append("\n🏅 排名信息:\n")
                    append("排名: 第${rank.rank}位 / 共${rank.total}人\n")
                    append("超越: ${rank.percentage}% 的玩家")
                }
            }
        }
        
        MaterialAlertDialogBuilder(this)
            .setTitle("游戏完成")
            .setMessage(message)
            .setPositiveButton("新游戏") { _, _ ->
                finish()
            }
            .setNeutralButton("查看排行榜") { _, _ ->
                val intent = Intent(this, LeaderboardActivity::class.java)
                startActivity(intent)
                finish()
            }
            .setNegativeButton("返回主页") { _, _ ->
                finish()
            }
            .setCancelable(false)
            .show()
    }
    
    private fun startTimer() {
        // 如果已经有计时器在运行，先停止它
        stopTimer()
        
        gameState.status = GameStatus.PLAYING
        gameState.startTime = System.currentTimeMillis()
        
        timer = Timer()
        timer?.scheduleAtFixedRate(object : TimerTask() {
            override fun run() {
                if (gameState.status == GameStatus.PLAYING) {
                    handler.post {
                        updateTimeDisplay()
                    }
                }
            }
        }, 1000, 1000)
    }
    
    private fun stopTimer() {
        timer?.cancel()
        timer = null
    }
    
    private fun updateTimeDisplay() {
        val elapsedSeconds = if (::gameState.isInitialized) {
            gameState.getElapsedSeconds()
        } else {
            0L
        }
        binding.tvTime.text = formatTime(elapsedSeconds)
    }
    
    private fun formatTime(seconds: Long): String {
        val minutes = seconds / 60
        val secs = seconds % 60
        return String.format("%02d:%02d", minutes, secs)
    }
    
    private fun updateScore() {
        // 简单的计分逻辑
        if (gameState.status == GameStatus.PLAYING) {
            gameState.score += 10
        }
        updateUI()
    }
    
    private fun updateUI() {
        binding.tvScore.text = "分数: ${gameState.score}"
        updateTimeDisplay()
    }
    
    private fun showLoading() {
        // TODO: 显示加载动画
    }
    
    private fun hideLoading() {
        // TODO: 隐藏加载动画
    }
    
    override fun onResume() {
        super.onResume()
        if (::gameState.isInitialized) {
            when (gameState.status) {
                GameStatus.PLAYING -> startTimer()
                GameStatus.PAUSED -> {
                    // 从暂停状态恢复，重新开始计时
                    gameState.status = GameStatus.PLAYING
                    startTimer()
                }
                else -> {}
            }
        }
    }
    
    override fun onPause() {
        super.onPause()
        if (::gameState.isInitialized && gameState.status == GameStatus.PLAYING) {
            // 只停止计时器，不改变游戏状态（除非用户主动暂停）
            stopTimer()
        }
    }
    
    override fun onDestroy() {
        super.onDestroy()
        stopTimer()
    }
} 